package com.example.my_bookkeeping;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.action.ViewActions.scrollTo;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.junit.Assert.assertTrue;

import android.app.Instrumentation;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

import androidx.test.espresso.ViewInteraction;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;

import com.example.my_bookkeeping.data.manager.CategoryManager;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

@LargeTest
@RunWith(AndroidJUnit4.class)
public class AddCategoryTest {

    @Rule
    public ActivityScenarioRule<MainActivity> mActivityScenarioRule =
            new ActivityScenarioRule<>(MainActivity.class);

    @After
    @Before
    public void setUp() {
        CategoryManager categoryManager = CategoryManager.getInstance();
        categoryManager.reset();
    }

    @Test
    public void addCategoryTest() {
        // 步骤1：导航到分类页面（修正匹配逻辑）
        ViewInteraction bottomNavigationItemView = onView(
                allOf(
                        withId(R.id.item_category),  // 通过id定位
                        withContentDescription("账目分类"),  // 通过contentDescription验证
                        isDisplayed()  // 确保视图可见
                )
        );
        bottomNavigationItemView.perform(click());

        // 步骤2：点击"添加分类"按钮
        ViewInteraction addCategoryButton = onView(
                allOf(withId(R.id.button_add_category), withText("添加类别"), // 确保文案与应用一致
                        isDisplayed()));
        addCategoryButton.perform(click());

        // 步骤3：选择分类类型（支出）
        ViewInteraction expenseRadioButton = onView(
                allOf(withId(R.id.rb_expense), withText("支出"), // 确保文案与应用一致
                        isDisplayed()));
        expenseRadioButton.perform(click());

        // 步骤4：输入分类名称（例如"交通"）
        ViewInteraction categoryNameInput = onView(
                allOf(withId(R.id.et_category_name),
                        isDisplayed()));
        categoryNameInput.perform(replaceText("交通"), closeSoftKeyboard());

        // 步骤5：点击确认按钮
        ViewInteraction confirmButton = onView(
                allOf(withId(android.R.id.button1), withText("确定"),
                        childAtPosition(
                                childAtPosition(
                                        withId(com.google.android.material.R.id.buttonPanel),
                                        0),
                                3)));
        confirmButton.perform(scrollTo(), click());

        // 步骤6：验证分类是否添加到单例Category中
        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
        instrumentation.runOnMainSync(() -> {
            // 获取单例实例
            CategoryManager categoryManager = CategoryManager.getInstance();
            // 检查支出分类列表是否包含新添加的"交通"
            assertTrue("支出分类列表应包含新添加的'交通'",
                    categoryManager.getExpenseCategoryList().contains("交通"));
        });
    }

    private static Matcher<View> childAtPosition(
            final Matcher<View> parentMatcher, final int position) {

        return new TypeSafeMatcher<View>() {
            @Override
            public void describeTo(Description description) {
                description.appendText("Child at position " + position + " in parent ");
                parentMatcher.describeTo(description);
            }

            @Override
            public boolean matchesSafely(View view) {
                ViewParent parent = view.getParent();
                return parent instanceof ViewGroup && parentMatcher.matches(parent)
                        && view.equals(((ViewGroup) parent).getChildAt(position));
            }
        };
    }
}
